package org.jing.r18.game.venusblood.lagoon;

import org.jing.core.lang.ExceptionHandler;
import org.jing.core.lang.data.Carrier;
import org.jing.core.logger.JingLogger;
import org.jing.r18.game.venusblood.lagoon.dto.Title;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;

/**
 * Description: <br>
 *
 * @author: bks <br>
 * @createDate: 2025-04-29 <br>
 */
@SuppressWarnings("DuplicatedCode")
public class AnalysisSave {
    private static final JingLogger LOGGER = JingLogger.getLogger(AnalysisSave.class);

    private AnalysisSave() {
        LOGGER.info("请输入读取存档编号:");
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            int saveIndex = scanner.nextInt();
            byte[] readBuffer = VBLHelper.getSaveBuffer(saveIndex);
            Carrier saveC = VBLHelper.getSaveData(readBuffer);
            LOGGER.info("载入完成, 请选择功能");
            ui(saveC);
            LOGGER.info("请确认是否覆盖存档(Y/N)");
            scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                if ("Y".equalsIgnoreCase(scanner.nextLine())) {
                    VBLHelper.writeSaveBuffer(saveIndex, readBuffer, saveC);
                }
            }
        }
    }

    private void ui(Carrier saveC) {
        while (true) {
            LOGGER.info("{}:更改游戏数据/{}:更改单位数据/{}:更改物品数据/{}:退出",
                VBLHelper.SAVE_MODEL_CHANGE_GAME,
                VBLHelper.SAVE_MODEL_CHANGE_UNIT,
                VBLHelper.SAVE_MODEL_CHANGE_ITEM,
                VBLHelper.SAVE_MODEL_QUIT);
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                int model = scanner.nextInt();
                switch (model) {
                    case 0: {
                        return;
                    }
                    case 1: {
                        changeGameData(saveC);
                        break;
                    }
                    case 2: {
                        changeUnitData(saveC);
                        break;
                    }
                    case 3: {
                        break;
                    }
                }
            }
        }
    }

    private void changeGameData(Carrier saveC) {
        while (true) {
            Carrier gameDataSetC = saveC.getCarrier("datas.userDataSet.gameData");
            int law = gameDataSetC.getNumber("_law").intValue();
            int chaos = gameDataSetC.getNumber("_chaos").intValue();
            int ruin = gameDataSetC.getNumber("_ruin").intValue();
            LOGGER.info("[law: {}][chaos: {}][ruin: {}]", law, chaos, ruin);
            int level = gameDataSetC.getNumber("_difficulty").intValue();
            int berserk = gameDataSetC.getNumber("_difficulty2").intValue();
            LOGGER.info("[level: {}][berserk: {}]", level, berserk);
            int turn = gameDataSetC.getNumber("_turn").intValue();
            int movePoint = gameDataSetC.getNumber("_moved").intValue();
            LOGGER.info("[turn: {}][movePoint: {}]", turn, movePoint);
            LOGGER.info("{}:修改law&chaos&ruin/{}:修改难度/{}:修改行动点&回合数/{}:退出",
                1,
                2,
                3,
                0);
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                int model = scanner.nextInt();
                switch (model) {
                    case 0: {
                        return;
                    }
                    case 1: {
                        LOGGER.info("请依次输入三个参数值, 以空格分割");
                        try {
                            scanner = new Scanner(System.in);
                            String[] vals = scanner.nextLine().split(" ");
                            law = Integer.parseInt(vals[0]);
                            chaos = Integer.parseInt(vals[1]);
                            ruin = Integer.parseInt(vals[2]);
                            gameDataSetC.setNumber("_law", law);
                            gameDataSetC.setNumber("_chaos", chaos);
                            gameDataSetC.setNumber("_ruin", ruin);
                        }
                        catch (Throwable t) {
                            LOGGER.info("非法输入, 请用依次输入三个值并用空格分割");
                        }
                        break;
                    }
                    case 2: {
                        LOGGER.info("请依次输入两个参数值, 以空格分割");
                        try {
                            scanner = new Scanner(System.in);
                            String[] vals = scanner.nextLine().split(" ");
                            level = Integer.parseInt(vals[0]);
                            berserk = Integer.parseInt(vals[1]);
                            gameDataSetC.setNumber("_difficulty", level);
                            gameDataSetC.setNumber("_difficulty2", berserk);
                        }
                        catch (Throwable t) {
                            LOGGER.info("非法输入, 请用依次输入两个值并用空格分割");
                        }
                        break;
                    }
                    case 3: {
                        LOGGER.info("请依次输入两个参数值, 以空格分割");
                        try {
                            scanner = new Scanner(System.in);
                            String[] vals = scanner.nextLine().split(" ");
                            turn = Integer.parseInt(vals[0]);
                            movePoint = Integer.parseInt(vals[1]);
                            gameDataSetC.setNumber("_turn", turn);
                            gameDataSetC.setNumber("_moved", movePoint);
                        }
                        catch (Throwable t) {
                            LOGGER.info("非法输入, 请用依次输入两个值并用空格分割");
                        }
                        break;
                    }
                }
            }
        }
    }

    private void changeUnitData(Carrier saveC) {
        Carrier unitsC = saveC.getCarrier("datas.userDataSet.unitData");
        int length = unitsC.getCount("_player");
        LOGGER.info("发现[{}]个单位数据", length);
        // 获取等级数据
        HashSet<Integer> growthSet = new HashSet<>();
        Carrier unitC;
        for (int i$ = 0; i$ < length; i$ ++) {
            unitC = unitsC.getCarrier(i$, "_player");
            int levelGrowth = unitC.getNumber("_levelData._growth").intValue();
            growthSet.add(levelGrowth);
        }
        List<Integer> growthList = new ArrayList<>(growthSet);
        growthList.sort(Integer::compareTo);
        while (true) {
            LOGGER.info("{}:检索单位/{}:修改等级上限/{}:修改单位称号/{}:退出",
                1,
                2,
                3,
                0);
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                int model = scanner.nextInt();
                switch (model) {
                    case 0: {
                        return;
                    }
                    case 1: {
                        queryUnitByExp(unitsC);
                        break;
                    }
                    case 2: {
                        changeUnitGrowth(unitsC, growthList);
                        break;
                    }
                    case 3: {
                        changeUnitTitle(unitsC);
                        break;
                    }
                }
            }
        }
    }

    private void queryUnitByExp(Carrier unitsC) {
        LOGGER.info("请输入目标单位当前经验值, 输入0退出");
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            String input = scanner.nextLine();
            if ("0".equals(input)) {
                return;
            }
            try {
                final int currentExp = Integer.parseInt(input);
                int length = unitsC.getCount("_player");
                Carrier unitC;
                for (int i$ = 0; i$ < length; i$++) {
                    unitC = unitsC.getCarrier(i$, "_player");
                    if (unitC.getNumber("_levelData._exp").intValue() == currentExp) {
                        LOGGER.info("过滤目标单位: [{}]@[{}]", unitC.getString("_id"), unitC.getString("_unique"));
                    }
                }
            }
            catch (Throwable t) {
                LOGGER.error(t);
            }
        }
    }

    private void changeUnitGrowth(Carrier unitsC, List<Integer> growthList) {
        LOGGER.info("目前等级链: [{}]", growthList);
        LOGGER.info("请依次输入起始等级、步长，以空格分割, 输入0退出");
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            try {
                String input = scanner.nextLine();
                if ("0".equals(input)) {
                    return;
                }
                String[] vals = input.split(" ");
                final int minLevel = Integer.parseInt(vals[0]);
                final int step = Integer.parseInt(vals[1]);
                LOGGER.info("使用新等级链替换, 最小等级为: [{}], 递增步长为: [{}]", minLevel, step);
                int length = unitsC.getCount("_player");
                String unitName;
                Carrier unitC;
                for (int i$ = 0; i$ < length; i$++) {
                    unitC = unitsC.getCarrier(i$, "_player");
                    unitName = unitC.getString("_unique");
                    int levelRank = unitC.getNumber("_levelData._rank").intValue();
                    int levelExp = unitC.getNumber("_levelData._exp").intValue();
                    int levelGrowth = unitC.getNumber("_levelData._growth").intValue();
                    LOGGER.info("[{}]: [Level: rank: {}/exp: {}/growth: {}]", unitName, levelRank, levelExp,
                        levelGrowth);
                    if (growthList.contains(levelGrowth)) {
                        unitC.setNumber("_levelData._growth",
                            VBLHelper.calcGrowthByLevel(minLevel + growthList.indexOf(levelGrowth) * step));
                    }
                }
            }
            catch (Throwable t) {
                LOGGER.error(t);
            }
        }
    }

    private void changeUnitTitle(Carrier unitsC) {
        LOGGER.info("请输入单位编号, 输入0退出");
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            try {
                String input = scanner.nextLine();
                if ("0".equals(input)) {
                    return;
                }
                String unitId = input;
                int length = unitsC.getCount("_player");
                Carrier unitC;
                for (int i$ = 0; i$ < length; i$ ++) {
                    unitC = unitsC.getCarrier(i$, "_player");
                    if (unitC.getString("_id").equals(unitId)) {
                        String unitName = unitC.getString("_unique");
                        LOGGER.info(">>>替换单位称号:[{}]@[{}]<<<", unitId, unitName);
                        LOGGER.info("请依次输入前缀和后缀称号编号, 以空格分割, 输入0退出");
                        showTitles();
                        Scanner scan = new Scanner(System.in);
                        if (scan.hasNextLine()) {
                            input = scan.nextLine();
                            if ("0".equals(input)) {
                                return;
                            }
                            try {
                                String[] vals = input.split(" ");
                                String prefixIndex = vals[0];
                                String suffixIndex = vals[1];
                                // 前缀
                                changeTitle(unitC, 1, prefixIndex);
                                // 后缀
                                changeTitle(unitC, 2, suffixIndex);

                                LOGGER.info(">>>称号更换完成:[{}]@[{}]<<<", unitId, unitName);
                            }
                            catch (Throwable t) {
                                LOGGER.error(t);
                            }
                        }
                    }
                }
            }
            catch (Throwable t) {
                LOGGER.error(t);
            }
        }
    }

    private void showTitles() {
        LOGGER.info("提示:");
        String[] showArr = {"468", "646", "553", "613", "565", "601", "605", "574", "649", "622", "577", "587", "603", "578", "644", "582", "600", "683", "708"};
        for (String i$ : showArr) {
            LOGGER.info(VBLHelper.filterTitle(i$).output());
        }
    }

    private void changeTitle(Carrier unitC, int index, String titleIndex) {
        ExceptionHandler.publishIfMatch(1 > index || index > 2, "非法称号索引");
        Title title = VBLHelper.filterTitle(titleIndex);
        index --;
        LOGGER.info("位置[{}]替换称号为:[{}]", index, title.output());
        Carrier titlesC = unitC.getCarrier(index, "_titles");
        Carrier skillC = unitC.getCarrier(index, "_skillTitle");
        titlesC.setNumber("_index", title.getIndex());
        titlesC.setString("_name", title.getName());
        skillC.setString("_id", title.getSkill().getId());
        skillC.setString("_name", title.getSkill().getName());
        skillC.setNumber("_power", title.getSkill().getPower());
        skillC.setNumber("_value", title.getSkill().getValue());
    }

    public static void main(String[] args) throws Exception {
        new AnalysisSave();
    }
}
